`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/08/16 16:05:39
// Design Name: 
// Module Name: gpio_ctl
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module gpio_ctl(
    input clk,
    input reset,
    
    inout [7:0] gpio,
    
    input bus_din_en,
    output [15:0] bus_din_data,
    input bus_dout_en,
    input [15:0] bus_dout_data,
    input [1:0] bus_dout_mask
    );

// BASE+    0 : gpio value R/W
// BASE+    1 : gpio in/out
reg [7:0] gpio_mode_io; // 0 => in; 1 => out;
reg [7:0] gpio_value;

wire [7:0] gpio_dout;

genvar i;

generate
    for (i = 0; i < 8; i=i+1) begin
        assign gpio[i] = gpio_mode_io[i] ? gpio_value[i] : 1'bz;
        assign gpio_dout[i] = gpio_mode_io[i] ? gpio_value[i] : gpio[i];
    end
endgenerate

assign bus_din_data = {gpio_mode_io, gpio_dout};

always @(posedge clk or posedge reset)
    if (reset) begin
        gpio_mode_io <= 0;
        gpio_value <= 0;
    end
    else begin
        if (bus_dout_en) begin
            if (bus_dout_mask[0])
                gpio_value <= bus_dout_data[7:0];
            if (bus_dout_mask[1])
                gpio_mode_io <= bus_dout_data[15:8];
        end
    end

endmodule
